Add Athenz integration module - #6321
Conversation
…sion when shading
5af1ac7 to
322bb7a
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6321 +/- ##
============================================
- Coverage 74.46% 74.43% -0.03%
- Complexity 22234 22967 +733
============================================
Files 1963 2061 +98
Lines 82437 85695 +3258
Branches 10764 11179 +415
============================================
+ Hits 61385 63791 +2406
- Misses 15918 16531 +613
- Partials 5134 5373 +239 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
jrhee17
left a comment
There was a problem hiding this comment.
I understood functionally this module is equivalent to ZPE lib and the ZTS lib but with an Armeria flavor.
| * @param tokenType the type of Athenz token to obtain | ||
| */ | ||
| public static Function<HttpClient, AthenzClient> newDecorator(ZtsBaseClient ztsBaseClient, | ||
| String domainName, TokenType tokenType) { |
There was a problem hiding this comment.
Question) I'm not sure of the environment, but is TokenType.ROLE_TOKEN often used? I'm wondering if TokenType.ACCESS_TOKEN should be the default
There was a problem hiding this comment.
Some LY internal servers only support ROLE_TOKEN type. So I wasn't sure if ACCESS_TOKEN could be a sensible default.
| * <pre>{@code | ||
| * class MyService { | ||
| * // 1. Decorate the method with `RequiresAthenzRole` to check Athenz role. | ||
| * @RequiresAthenzRole(resource = "user", action = "get") |
There was a problem hiding this comment.
Note) I understood this is an AND condition. i.e.) If users want to allow either both ACCESS_TOKEN and ROLE_TOKEN, they can't do it using the annotations.
There was a problem hiding this comment.
If tokenType is unset, ACCESS_TOKEN and ROLE_TOKEN are allowed.
| private AthenzPolicyConfig policyConfig; | ||
| private int maxTokenCacheSize = MAX_TOKEN_CACHE_SIZE; | ||
|
|
||
| AbstractAthenzServiceBuilder(ZtsBaseClient ztsBaseClient) { |
There was a problem hiding this comment.
The external zpu cronjob to fetch policies is no longer necessary.
I actually understood the zpu cronjob is still necessary since AthenzService still needs to use the credentials created/rotated by the zpu when connecting to zts. Let me know if I misunderstood.
There was a problem hiding this comment.
ZPU fetches and refreshes Athenz policy files. IIUC, it is not related to credentials. Generally, creating Service credentials is delegated to Athenz SIA, which is still necessary.
https://github.com/AthenZ/athenz/blob/master/docs/system_view.md#sia-service-identity-agent-provider:~:text=for%20issuing%20tokens.-,SIA%20(Service%20Identity%20Agent,can%20validate%20the%20signature.,-ZPE%20(AuthZ%20Policy
There was a problem hiding this comment.
I see. I understood that service providers will need to install either an SIA and use this module, or use ZPU with ZPE
There was a problem hiding this comment.
This Athenz module does not support creating Service credentials, so an external system such as SIA is still used for mTLS.
There was a problem hiding this comment.
I see. Then I understood that the ZPU internally uses SIA to acquire initial credentials for communication with the ZMS/ZTS then.
Motivation: Athenz SIA refreshes the certs every 24 hours by default. https://github.com/AthenZ/k8s-athenz-identity#configuration In order to comply with the specification, `TlsProvider` should detect the updated certs and automatically refresh them. Additionally, there were similar requests from Armeria users. #6054 Modifications: - Add `RefreshingTlsProvider` that periodically refreshes the given `TlsKeyPair` provider. - Currently, only one `TlsKeyPair` is supported for `RefreshingTlsProvider` - TODO) Integrate `MappedTlsProvider` with `RefreshingTlsProvider` to build a more flexible `TlsProvider` using `TlsProviderBuilder` - Expose `ReflectiveDependencyInjector` via public API via `DependencyInjector.ofReflective()` - This is unrelated to this PR, but added to minimize conflicts when merging the main branch into #6321 Result: You can now periodically refresh `TlsKeyPair` when using `TlsProvider.ofSheduled()` ```java File keyFile = ...; Fie certFile = ...; TlsProvider.ofScheduled(() -> { return TlsKeyPair.of(keyFile, certFile); }, Duration.ofHours(1)); ```
Motivation:
This PR aims to provide an integration layer for Athenz so that users can easily obtain Athenz tokens and validate them
by decorating clients or services and annotating required Athenz roles declaratively.
Modifications:
ZtsBaseClientprovides common functionality such asTlsKeyPairmanagement and Athenz client configurations.ZtsBaseClientfirst to createAthenzClientandAthenzService.ZtsBaseClientis designed as a resource, and it needs to be closed since Armeria decorators are not closable.ClientFactoryis delegated toZtsBaseClientAccessTokenClientacquires OAuth 2.0 token from the/oauth2/tokenendpoint.RoleTokenClientobtains Athenz role tokens from the/domain/{domainName}/token?role=<roleName>endpoint.AccessTokenClient.AthenzClientis a public decorator that delegates toAccessTokenClientorRoleTokenClientdepending on the configuration.AthenzPolicyLoaderloads Athenz domain policies from ZTS servers, just like thezpuCLI does.zpucronjob to fetch policies is no longer necessary.AthenzPolicyHandlerparses the policy data and verifies it with public keys.MinifiedAuthZpeClientis forked fromAuthZpeClientand modified to seamlessly integrate with Armeria.MinifiedAuthZpeClientis responsible for token validation.AthenzServiceis a public decorator to check access permission for projected resources.RequiresAthenzRoleallows users to specify an Athenz role using annotations.AthenzServiceDecoratorFactoryshould be injected viaDependencyInjectorto useRequiresAthenzRoleResult: